package mi.payment.admin.pay88;

import android.text.TextUtils;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.MarshalBase64;
import org.ksoap2.serialization.MarshalDate;
import org.ksoap2.serialization.MarshalFloat;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import lainey.ui.utils.LogUtil;
import mi.payment.Constant;
import mi.payment.bean.db.TradeData;
import mi.payment.db.dao.PayDetail;
import mi.payment.utils.ByteUtil;
import mi.payment.utils.DateUtil;
import mi.payment.utils.MoneyUtils;
import mi.payment.utils.ShaUtil;

public class WebServiceApi {

    private static WebServiceApi sInstance;

    private WebServiceApi() {

    }

    public static WebServiceApi getInstance() {
        if (sInstance == null) {
            sInstance = new WebServiceApi();
        }
        return sInstance;
    }

    public TradeData saleTransaction(TradeData tradeData, boolean isMerchantScan) throws Exception {
        String nameSpace = "https://www.mobile88.com";
        String methodName = "EntryPageFunctionality";
        String endPoint = "https://payment.ipay88.com/ePayment/WebService/MHGatewayService/GatewayService.svc";
        String soapAction = "https://www.mobile88.com/IGatewayService/EntryPageFunctionality";

        PayDetail payDetail = tradeData.getPayDetail();
        IPay88Bean bean = IPay88Operation.getInstance().getIPay88Bean();

        String date = DateUtil.getDateForYyyyMMdd();
        date = date.replaceAll(" ", "").replaceAll("-", "").replaceAll(":", "");

        SoapObject request = new SoapObject(nameSpace, methodName);

        ClientRequestModel req = new ClientRequestModel();
        req.Amount = MoneyUtils.longCent2DoubleMoneyStr(payDetail.amount);
        req.RefNo = "P" + date + payDetail.voucherNo;
        req.BarcodeNo = payDetail.payQRCode;
        req.PaymentId = payDetail.transPlatform;
        req.BackendURL = "https://www.sunmi.com/";

        req.Currency = payDetail.currency;
        req.Remark = "iPay88 pay product";
        req.ProdDesc = bean.merchantName + date + " product";

        req.TerminalID = bean.merchantID;
        req.MerchantCode = bean.merchantCode;

        req.UserContact = "0123456789";
        req.UserEmail = "chloe.wong@ipay88.com.my";
        req.UserName = "iPay88";
        req.lang = "UTF-8";

        req.xfield1 = "Lee Dawn";
        req.xfield2 = "Lee Dawn";

        req.SignatureType = "SHA256";

        // 计算请求的签名
        String amountStr = req.Amount.replaceAll("\\.", "").replaceAll(",", "");
        String encryptStr;
        if (isMerchantScan) {
            encryptStr = bean.merchantKey + bean.merchantCode + req.RefNo + amountStr + req.Currency + req.BarcodeNo;
        } else {
            encryptStr = bean.merchantKey + bean.merchantCode + req.RefNo + req.PaymentId + amountStr + req.Currency;
        }
        byte[] dataBytes = encryptStr.getBytes();
        dataBytes = ShaUtil.sha_256(dataBytes);
        String signature = ByteUtil.bytes2HexStrToLower(dataBytes);
        LogUtil.e(Constant.TAG, "sale request amountStr: " + amountStr);
        LogUtil.e(Constant.TAG, "sale request encryptStr: " + encryptStr);
        LogUtil.e(Constant.TAG, "sale request signature: " + signature);

        req.Signature = signature;

        PropertyInfo property = new PropertyInfo();
        property.setValue(req);
        property.name = "requestModelObj";
        property.type = ClientRequestModel.class;

        request.addProperty(property);

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = true;
        envelope.bodyOut = request;
        envelope.setOutputSoapObject(request);

        new MarshalDate().register(envelope);

        // Now you have to add mapping to map the local class created, to the one on the server
        envelope.addMapping("http://schemas.datacontract.org/2004/07/MHPHGatewayService.Model", "ClientRequestModel", ClientRequestModel.class);

        // Add marshalling (this one might not be necessary, but ill just add it)
        new MarshalFloat().register(envelope);
        new MarshalBase64().register(envelope);

        HttpTransportSE transport = new HttpTransportSE(endPoint);
        transport.debug = true;
        transport.call(soapAction, envelope);
        SoapObject object = (SoapObject) envelope.bodyIn;
        String result = object.toString();
        LogUtil.e(Constant.TAG, "WebService: " + result);

        object = (SoapObject) object.getProperty(0);
        String responseRefNo = object.getPropertyAsString("RefNo");
        String responseAmount = object.getPropertyAsString("Amount");
        String responseTransId = object.getPropertyAsString("TransId");
        String responseCurrency = object.getPropertyAsString("Currency");
        String responseMerchantCode = object.getPropertyAsString("MerchantCode");
        String responsePaymentId = object.getPropertyAsString("PaymentId");
        boolean hasProperty = object.hasProperty("QRCode");
        if (hasProperty) {
            String responseQRCode = object.getPropertySafelyAsString("QRCode");
            LogUtil.e(Constant.TAG, "responseQRCode: " + responseQRCode);
        }
        hasProperty = object.hasProperty("QRValue");
        if (hasProperty) {
            String responseQRValue = object.getPropertySafelyAsString("QRValue");
            LogUtil.e(Constant.TAG, "responseQRValue: " + responseQRValue);
            payDetail.payQRCode = responseQRValue;
        }
        hasProperty = object.hasProperty("ErrDesc");
        if (hasProperty) {
            String responseErrDesc = object.getPropertySafelyAsString("ErrDesc");
            LogUtil.e(Constant.TAG, "responseErrDesc: " + responseErrDesc);
            payDetail.tradeResultDes = responseErrDesc;
        }
        String responseStatus = object.getPropertyAsString("Status");
        String responseSignature = object.getPropertyAsString("Signature");
        LogUtil.e(Constant.TAG, "Status: " + responseStatus + " Signature: " + responseSignature);

        // 计算返回的签名
        amountStr = responseAmount.replaceAll("\\.", "").replaceAll(",", "");
        encryptStr = bean.merchantKey + responseMerchantCode + responsePaymentId + responseRefNo + amountStr + responseCurrency + responseStatus;
        dataBytes = encryptStr.getBytes();
        dataBytes = ShaUtil.sha_256(dataBytes);
        signature = ByteUtil.bytes2HexStrToLower(dataBytes);
        LogUtil.e(Constant.TAG, "sale response amountStr: " + amountStr);
        LogUtil.e(Constant.TAG, "sale response encryptStr: " + encryptStr);
        LogUtil.e(Constant.TAG, "sale response signature: " + signature);

        payDetail.referNo = responseRefNo;
        payDetail.thirdTransNum = responseTransId;
        payDetail.tempTerminalNo = bean.merchantID;
        payDetail.tempMerchantNo = bean.merchantCode;
        payDetail.tempMerchantName = bean.merchantName;

        boolean equalsStatus = TextUtils.equals("1", responseStatus);
        boolean equals = TextUtils.equals(responseSignature, signature);
        if (isMerchantScan && equals && equalsStatus) {
            payDetail.QRCodeTransState = 1;
            payDetail.tradeAnswerCode = "00";
        } else {
            if (equals && equalsStatus) {
                payDetail.QRCodeTransState = 2;
                payDetail.tradeAnswerCode = "00";
            } else {
                payDetail.QRCodeTransState = -1;
                payDetail.tradeAnswerCode = Constant.ANSWER_CODE_FAILED;
            }
        }
        return tradeData;
    }

    public TradeData voidTransaction(TradeData tradeData) throws Exception {
        String nameSpace = "https://www.mobile88.com";
        String methodName = "VoidTransaction";
        String endPoint = "https://payment.ipay88.com.my/epayment/webservice/voidapi/voidfunction.asmx";
        String soapAction = "https://www.mobile88.com/VoidTransaction";

        PayDetail payDetail = tradeData.getPayDetail();
        IPay88Bean bean = IPay88Operation.getInstance().getIPay88Bean();

        SoapObject request = new SoapObject(nameSpace, methodName);
        String moneyStr = MoneyUtils.longCent2DoubleMoneyStr(payDetail.amount);
        String currency;
        if (payDetail.transPlatform == 296 || payDetail.transPlatform == 308) {
            currency = "CNY";
        } else {
            currency = "MYR";
        }
        request.addProperty("amount", moneyStr);
        request.addProperty("currency", currency);
        request.addProperty("MerchantCode".toLowerCase(), bean.merchantCode);
        request.addProperty("ccTransId".toLowerCase(), payDetail.thirdTransNum);

        // 计算请求的签名
        String amountStr = moneyStr.replaceAll("\\.", "").replaceAll(",", "");
        String encryptStr = bean.merchantKey + bean.merchantCode + payDetail.thirdTransNum + amountStr + currency;
        byte[] dataBytes = encryptStr.getBytes();
        dataBytes = ShaUtil.sha_256(dataBytes);
        String signature = ByteUtil.bytes2HexStrToLower(dataBytes);
        LogUtil.e(Constant.TAG, "void request amountStr: " + amountStr);
        LogUtil.e(Constant.TAG, "void request encryptStr: " + encryptStr);
        LogUtil.e(Constant.TAG, "request signature: " + signature);

        request.addProperty("Signature", signature);

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);
        envelope.dotNet = true;
        envelope.bodyOut = request;
        envelope.setOutputSoapObject(request);

        HttpTransportSE transport = new HttpTransportSE(endPoint);
        transport.debug = true;
        transport.call(soapAction, envelope);
        SoapObject object = (SoapObject) envelope.bodyIn;
        String result = object.toString();
        LogUtil.e(Constant.TAG, "WebService: " + result);

        payDetail.tempTerminalNo = bean.merchantID;
        payDetail.tempMerchantNo = bean.merchantCode;
        payDetail.tempMerchantName = bean.merchantName;

        String responseVoidTransactionResult = object.getPropertyAsString("VoidTransactionResult");
        boolean equals = TextUtils.equals(responseVoidTransactionResult, "0") || TextUtils.equals(responseVoidTransactionResult, "9999");
        if (equals) {
            payDetail.QRCodeTransState = 1;
            payDetail.tradeAnswerCode = "00";
        } else {
            payDetail.QRCodeTransState = -1;
            payDetail.tradeAnswerCode = responseVoidTransactionResult;
        }
        return tradeData;
    }


}
